home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / mach / sun4.md / machMigrate.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  9KB  |  302 lines

  1. /* 
  2.  * machMigrate.c --
  3.  *
  4.  *         Machine dependent code to support process migration.  These routines
  5.  *         encapsulate and deencapsulate the machine-dependent state of a
  6.  *    process and set up the state of the process on its new machine.
  7.  *
  8.  * Copyright 1988 Regents of the University of California
  9.  * Permission to use, copy, modify, and distribute this
  10.  * software and its documentation for any purpose and without
  11.  * fee is hereby granted, provided that the above copyright
  12.  * notice appear in all copies.  The University of California
  13.  * makes no representations about the suitability of this
  14.  * software for any purpose.  It is provided "as is" without
  15.  * express or implied warranty.
  16.  */
  17.  
  18. #ifndef lint
  19. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/mach/sun4.md/machMigrate.c,v 1.6 91/08/02 18:43:26 mgbaker Exp $ SPRITE (Berkeley)";
  20. #endif /* not lint */
  21.  
  22. #include "sprite.h"
  23. #include "machConst.h"
  24. #include "machInt.h"
  25. #include "mach.h"
  26. #include "machMon.h"
  27. #include "sched.h"
  28. #include "procMigrate.h"
  29.  
  30. #include <stdio.h>
  31. #include <bstring.h>
  32.  
  33. /*
  34.  * The information that is transferred between two machines.
  35.  */
  36. typedef struct MigratedState {
  37.     Mach_RegState    trapRegs;    /* The pointer to trapRegs in state
  38.                      * should be set to point to this in the
  39.                      * deencap routine.  It usually
  40.                      * points to the kernel stack, but
  41.                      * this won't exist yet on a
  42.                      * migrated process. */
  43.     int            fpuStatus;    /* See Mach_State. */
  44.     int            lastSysCall;    /* Used in sys module. */
  45.     int            savedArgI0;    /* Arg 0 saved for sys call. */
  46. } MigratedState;
  47.  
  48.  
  49. /*
  50.  * ----------------------------------------------------------------------------
  51.  *
  52.  * Mach_EncapState --
  53.  *
  54.  *    Copy the machine-dependent information for a process into
  55.  *    a buffer.  The buffer passed to the routine must contain space for
  56.  *    a MigratedState structure, the size of which is accessible via 
  57.  *    another procedure.  
  58.  *
  59.  * Results:
  60.  *      SUCCESS.
  61.  *    The buffer is filled with the user state and PC of the process.
  62.  *
  63.  * Side effects:
  64.  *    None.
  65.  *
  66.  * ----------------------------------------------------------------------------
  67.  */
  68. /* ARGSUSED */
  69. ReturnStatus
  70. Mach_EncapState(procPtr, hostID, infoPtr, buffer)
  71.     register Proc_ControlBlock     *procPtr;  /* The process being migrated */
  72.     int hostID;                   /* host to which it migrates */
  73.     Proc_EncapInfo *infoPtr;           /* area w/ information about
  74.                         * encapsulated state */
  75.     Address buffer;               /* Pointer to allocated buffer */
  76. {
  77.     Mach_State *machStatePtr = procPtr->machStatePtr;
  78.     MigratedState *migPtr = (MigratedState *) buffer;
  79.  
  80.     if (machStatePtr->fpuStatus & MACH_FPU_ACTIVE) {
  81.     if (proc_MigDebugLevel > 2) {
  82.         printf("Mach_EncapState: FPU was active (fsr %x), dumping state.\n",
  83.            procPtr->machStatePtr->fpuStatus);
  84.     }
  85.     /*
  86.      * We may or may not have saved the floating point state from the
  87.      * FPU.  If an exception is pending then we must of done a 
  88.      * save and doing another will overwrite the exception. 
  89.      */
  90.     if ((machStatePtr->fpuStatus & MACH_FPU_EXCEPTION_PENDING) == 0) {
  91.         MachFPUDumpState(machStatePtr->trapRegs);
  92.         if (machStatePtr->fpuStatus & MACH_FPU_EXCEPTION_PENDING) {
  93.         machStatePtr->fpuStatus |= 
  94.             (machStatePtr->trapRegs->fsr & MACH_FSR_TRAP_TYPE_MASK);
  95.         }
  96.     }
  97.     if (proc_MigDebugLevel > 2) {
  98.         printf("Mach_EncapState: FPU fsr now %x.\n",
  99.            procPtr->machStatePtr->fpuStatus);
  100.     }
  101.     }
  102.     /*
  103.      * There must not be any saved window state for migration.  This shouldn't
  104.      * ever happen the way things are set up.
  105.      */
  106.     if (machStatePtr->savedMask != 0) {
  107.     panic("Mach_EncapState: saved window state of proc isn't empty.\n");
  108.     }
  109.     bcopy((Address) machStatePtr->trapRegs, (Address) &migPtr->trapRegs,
  110.         sizeof (Mach_RegState));
  111.     /* Copy necessary fields from state structure. */
  112.     migPtr->fpuStatus = machStatePtr->fpuStatus;
  113.     migPtr->lastSysCall = machStatePtr->lastSysCall;
  114.     migPtr->savedArgI0 = machStatePtr->savedArgI0;
  115.  
  116.     return(SUCCESS);
  117. }    
  118.     
  119.  
  120. /*
  121.  * ----------------------------------------------------------------------------
  122.  *
  123.  * Mach_DeencapState --
  124.  *
  125.  *    Copy the machine-dependent information for a process from
  126.  *    a buffer.  The buffer passed to the routine must contain
  127.  *    a MigratedState structure created by Mach_EncapState on the
  128.  *    machine starting a migration.  
  129.  *
  130.  * Results:
  131.  *    The user state and PC of the process are initialized from the
  132.  *    encapsulated information, and the other standard process
  133.  *    initialization operations are performed (by the general initialization
  134.  *    procedure).  The status from that procedure is returned.
  135.  *
  136.  * Side effects:
  137.  *    None.
  138.  *
  139.  * ----------------------------------------------------------------------------
  140.  */
  141. /* ARGSUSED */
  142. ReturnStatus
  143. Mach_DeencapState(procPtr, infoPtr, buffer)
  144.     register Proc_ControlBlock     *procPtr; /* The process being migrated */
  145.     Proc_EncapInfo *infoPtr;          /* information about the buffer */
  146.     Address buffer;              /* buffer containing data */
  147. {
  148.     MigratedState *migPtr = (MigratedState *) buffer;
  149.     Mach_State    state;
  150.     ReturnStatus status;
  151.  
  152.     if (infoPtr->size != sizeof(MigratedState)) {
  153.     if (proc_MigDebugLevel > 0) {
  154.         printf("Mach_DeencapState: warning: host %d tried to migrate",
  155.         procPtr->peerHostID);
  156.         printf(" onto this host with wrong structure size.");
  157.         printf("  Ours is %d, theirs is %d.\n",
  158.         sizeof(MigratedState), infoPtr->size);
  159.     }
  160.     return(PROC_MIGRATION_REFUSED);
  161.     }
  162.  
  163.  
  164.     /*
  165.      * Get rid of the process's old machine-dependent state if it exists.
  166.      */
  167.     if (procPtr->machStatePtr != (Mach_State *) NIL) {
  168.     Mach_FreeState(procPtr);
  169.     }
  170.  
  171.     bzero((char *) &state, sizeof (Mach_State));
  172.     state.switchRegs = (Mach_RegState *) NIL;
  173.     /*
  174.      * Set trapRegs to the trapRegs area of the migrated state.
  175.      */
  176.     state.trapRegs = &migPtr->trapRegs;
  177.     /* Get other necessary fields for Mach_State structure. */
  178.     state.fpuStatus = migPtr->fpuStatus;
  179.     state.lastSysCall = migPtr->lastSysCall;
  180.     state.savedArgI0 = migPtr->savedArgI0;
  181.  
  182.     /* Don't pass the pc explicitly -- it will be gotten from trapRegs. */
  183.     status = Mach_SetupNewState(procPtr, &state,
  184.         Proc_ResumeMigProc, (Address)NIL, TRUE);
  185.  
  186.     /*
  187.      * Mach_SetupNewState thinks that all new processes have a clean FPU
  188.      * slate, and it zeroes the mach state.  Make sure to keep any
  189.      * pending exceptions.
  190.      */
  191.     if (proc_MigDebugLevel > 2) {
  192.     printf("Mach_DeencapState: FPU status register was %x.\n",
  193.            migPtr->fpuStatus);
  194.     }
  195.     if (migPtr->fpuStatus) {
  196.     procPtr->machStatePtr->fpuStatus = migPtr->fpuStatus;
  197.     procPtr->specialHandling = 1;
  198.     }
  199.     
  200.     
  201.     return(status);
  202. }    
  203.     
  204.  
  205.  
  206. /*
  207.  * ----------------------------------------------------------------------------
  208.  *
  209.  * Mach_GetEncapSize --
  210.  *
  211.  *    Return the size of the encapsulated machine-dependent data.
  212.  *
  213.  * Results:
  214.  *    SUCCESS is returned directly; the size of the encapsulated state
  215.  *    is returned in infoPtr->size.
  216.  *
  217.  * Side effects:
  218.  *    None.
  219.  *
  220.  * ----------------------------------------------------------------------------
  221.  *
  222.  */
  223.  
  224. /* ARGSUSED */
  225. ReturnStatus
  226. Mach_GetEncapSize(procPtr, hostID, infoPtr)
  227.     Proc_ControlBlock *procPtr;            /* process being migrated */
  228.     int hostID;                    /* host to which it migrates */
  229.     Proc_EncapInfo *infoPtr;            /* area w/ information about
  230.                          * encapsulated state */
  231. {
  232.     infoPtr->size = sizeof(MigratedState);
  233.     return(SUCCESS);
  234. }
  235.  
  236.  
  237. /*
  238.  * ----------------------------------------------------------------------------
  239.  *
  240.  * Mach_CanMigrate --
  241.  *
  242.  *    Indicate whether a process's trapstack is in a form suitable for
  243.  *    starting a migration.  We require that nextPc follow pc -- if
  244.  *     we just did a jump, then we defer migration momentarily.
  245.  *
  246.  * Results:
  247.  *    TRUE if we can migrate using this trapstack, FALSE otherwise.
  248.  *
  249.  * Side effects:
  250.  *    None.
  251.  *
  252.  * ----------------------------------------------------------------------------
  253.  */
  254. Boolean
  255. Mach_CanMigrate(procPtr)
  256.     Proc_ControlBlock *procPtr;        /* pointer to process to check */
  257. {
  258.     Boolean okay;
  259.     Mach_RegState *regsPtr;
  260.     
  261.     okay = TRUE;
  262.     regsPtr = procPtr->machStatePtr->trapRegs;
  263.  
  264.  
  265.     if (regsPtr->nextPc != regsPtr->pc + 4) {
  266.     okay = FALSE;
  267.     }
  268.     if (proc_MigDebugLevel > 4) {
  269.     printf("Mach_CanMigrate called. PC %x, returning %d.\n",
  270.            regsPtr->pc, okay);
  271.     }
  272.     return okay;
  273. }    
  274.  
  275.  
  276. /*
  277.  *----------------------------------------------------------------------
  278.  *
  279.  * Mach_GetLastSyscall --
  280.  *
  281.  *    Return the number of the last system call performed for the current
  282.  *    process.
  283.  *
  284.  * Results:
  285.  *    The system call number is returned.
  286.  *
  287.  * Side effects:
  288.  *    None.
  289.  *
  290.  *----------------------------------------------------------------------
  291.  */
  292.  
  293. int
  294. Mach_GetLastSyscall()
  295. {
  296.     Proc_ControlBlock *procPtr;        /* pointer to process to check */
  297.  
  298.     procPtr = Proc_GetCurrentProc();
  299.  
  300.     return(procPtr->machStatePtr->lastSysCall);
  301. }
  302.